1 /******************************************************************************* 2 * Copyright (c) 2000, 2011 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.swt.custom; 15 16 17 import org.eclipse.swt.*; 18 import org.eclipse.swt.graphics.*; 19 import org.eclipse.swt.widgets.*; 20 21 /** 22 * Support for showing a Busy Cursor during a long running process. 23 * 24 * @see <a href="http://www.eclipse.org/swt/snippets/#busyindicator">BusyIndicator snippets</a> 25 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 26 */ 27 public class BusyIndicator { 28 29 static int nextBusyId = 1; 30 static final String BUSYID_NAME = "SWT BusyIndicator"; //$NON-NLS-1$ 31 static final String BUSY_CURSOR = "SWT BusyIndicator Cursor"; //$NON-NLS-1$ 32 33 /** 34 * Runs the given <code>Runnable</code> while providing 35 * busy feedback using this busy indicator. 36 * 37 * @param display the display on which the busy feedback should be 38 * displayed. If the display is null, the Display for the current 39 * thread will be used. If there is no Display for the current thread, 40 * the runnable code will be executed and no busy feedback will be displayed. 41 * @param runnable the runnable for which busy feedback is to be shown. 42 * Must not be null. 43 * 44 * @exception IllegalArgumentException <ul> 45 * <li>ERROR_NULL_ARGUMENT - if the runnable is null</li> 46 * </ul> 47 */ 48 showWhile(Display display, Runnable runnable)49 public static void showWhile(Display display, Runnable runnable) { 50 if (runnable == null) 51 SWT.error(SWT.ERROR_NULL_ARGUMENT); 52 if (display == null) { 53 display = Display.getCurrent(); 54 if (display == null) { 55 runnable.run(); 56 return; 57 } 58 } 59 60 Integer busyId = Integer.valueOf(nextBusyId); 61 nextBusyId++; 62 Cursor cursor = display.getSystemCursor(SWT.CURSOR_WAIT); 63 Shell[] shells = display.getShells(); 64 for (Shell shell : shells) { 65 Integer id = (Integer)shell.getData(BUSYID_NAME); 66 if (id == null) { 67 setCursorAndId(shell, cursor, busyId); 68 } 69 } 70 71 try { 72 runnable.run(); 73 } finally { 74 shells = display.getShells(); 75 for (Shell shell : shells) { 76 Integer id = (Integer)shell.getData(BUSYID_NAME); 77 if (id == busyId) { 78 setCursorAndId(shell, null, null); 79 } 80 } 81 } 82 } 83 84 /** 85 * Paranoia code to make sure we don't break UI because of one shell disposed, see bug 532632 comment 20 86 */ setCursorAndId(Shell shell, Cursor cursor, Integer busyId)87 private static void setCursorAndId(Shell shell, Cursor cursor, Integer busyId) { 88 if (!shell.isDisposed()) { 89 shell.setCursor(cursor); 90 } 91 if (!shell.isDisposed()) { 92 shell.setData(BUSYID_NAME, busyId); 93 } 94 } 95 } 96